﻿using CuaHangLego.DataAccess;
using CuaHangLego.Model;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;

namespace CuaHangLego.Bussiness
{
    public class SanPhamKhoBSS : IModelBSS<SanPhamKho>
    {
        public IList<SanPhamKho> ListSP { get; private set; }
        public bool IsShowInVisible = false;

        public SanPhamKhoBSS()
        {
            this.ListSP = new List<SanPhamKho>();
        }

        public void ShowInVisible()
        {
            this.IsShowInVisible = true;
        }

        public void HideInVisible()
        {
            this.IsShowInVisible = false;
        }

        public void UpdateData()
        {
            if(IsShowInVisible) this.ListSP = SanPhamKhoDA.Instance.GetAll();
            else this.ListSP = SanPhamKhoDA.Instance.GetAllWithoutDeletedItem();
        }

        public void Add(SanPhamKho item)
        {
            item.StateType = BaseModel.StateTypes.WillBeAdd;
            this.ListSP.Add(item);
        }

        public void Edit(SanPhamKho item)
        {
            item.StateType = BaseModel.StateTypes.WillBeChange;
            for (int i = 0; i < this.ListSP.Count; i++)
            {
                if (this.ListSP[i].MaSo == item.MaSo)
                {
                    this.ListSP[i] = item;
                    break;
                }
            }
        }

        public void Remove(SanPhamKho item)
        {
            item.StateType = BaseModel.StateTypes.WillBeRemove;
            for (int i = 0; i < this.ListSP.Count; i++)
            {
                if (this.ListSP[i].MaSo == item.MaSo)
                {
                    this.ListSP[i] = item;
                    break;
                }
            }
        }

        public Hashtable Commit()
        {
            IList<string> missingInsert = new List<string>();
            IList<string> missingUpdate = new List<string>();
            IList<string> missingDelete = new List<string>();
            Hashtable missing = new Hashtable();
            int rsint = -1;
            bool rsbool = false;
            foreach (SanPhamKho kspr in this.ListSP)
            {
                switch (kspr.StateType)
                {
                    case BaseModel.StateTypes.WillBeAdd:
                        rsint = SanPhamKhoDA.Instance.Insert(kspr);
                        if (rsint < 0) missingInsert.Add(kspr.Ten);
                        break;
                    case BaseModel.StateTypes.WillBeChange:
                        rsbool = SanPhamKhoDA.Instance.Update(kspr);
                        if (!rsbool) missingUpdate.Add(kspr.Ten);
                        break;
                    case BaseModel.StateTypes.WillBeRemove:
                        rsbool = SanPhamKhoDA.Instance.Delete(kspr);
                        if (!rsbool) missingUpdate.Add(kspr.Ten);
                        break;
                    default:
                        break;
                }
            }
            
            missing.Add("insert", missingInsert);
            missing.Add("update", missingUpdate);
            missing.Add("delete", missingDelete);

            return missing;
        }

        public IList<SanPhamKho> GetSanPhamBy(string key)
        {
            if (IsShowInVisible)
                return this.ListSP.Where(sp => sp.Ten.ToLower().Contains(key.ToLower())
                || sp.ChuDe.Ten.ToLower().Contains(key.ToLower())).ToList();
            else return this.ListSP.Where(sp => (sp.IsVisible && (sp.Ten.ToLower().Contains(key.ToLower())
                || sp.ChuDe.Ten.ToLower().Contains(key.ToLower())))).ToList();
        }

        public IList<SanPhamKho> GetAll()
        {
            return this.ListSP;
        }

        public void UploadImage(string filePath, string fileName)
        {
            string url = "http://localhost:7190/SaveImage.aspx";
                string boundary = string.Format("----------------------------{0}", DateTime.Now.Ticks.ToString("x"));//The boundary for the file(s) to upload
 
                HttpWebRequest uploadImageHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);//used to upload the image to theh server
                uploadImageHttpWebRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);//indicating the boundary and content type
                uploadImageHttpWebRequest.Method = "POST";//indicatingthat we are using POST tosend the data to the server
                uploadImageHttpWebRequest.KeepAlive = true;
 
                Stream memStream = new System.IO.MemoryStream();//used to collect the necessaryinformation to send to the server...starting with the beginning ;boundary 
                byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
                memStream.Write(boundarybytes, 0, boundarybytes.Length);
 
                //string[] fileNameTokens = filePath.Split('\\');//retrieving the file's name
                //string fileName = string.Format("{0}{1}",DateTime.Now.Ticks.ToString("x"),fileNameTokens[fileNameTokens.Length - 1]);//genearting a unique ;file name to save on the ;server
 
                //indicatingthe Key for the file that we are uploading ('name') and the name of the file aswe want it to appear onthe server ('filename')
                string header = string.Format("Content-Disposition:form-data; name=\"imageToUpload\"; filename=\"{0}\"\r\n Content-Type: application/octet-stream\r\n\r\n", fileName);
                byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
                memStream.Write(headerbytes, 0, headerbytes.Length);
 
                //Readingthe file and writing it tothe memStream
                using (FileStream fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read))
                {
                   byte[] buffer = new byte[1024];
                   int bytesRead = 0;
                   while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) !=0)
                   {
                       memStream.Write(buffer, 0, bytesRead);
                   }
 
                }
 
                //writingthe closing boundary 
                memStream.Write(boundarybytes, 0, boundarybytes.Length);
                uploadImageHttpWebRequest.ContentLength = memStream.Length; //indicating the length of the content
                Stream requestStream = uploadImageHttpWebRequest.GetRequestStream();//retrieving the stream that will be used to uploadthe file to the server
 
                //writingthe memory stream into a byte array and writing that bytearray to the stream used to upload the file to the ;server
                memStream.Position = 0;
                byte[] tempBuffer = new byte[memStream.Length];
                memStream.Read(tempBuffer, 0, tempBuffer.Length);
                memStream.Close();//cleaning up our memory stream since we aren't using itany more
 
                requestStream.Write(tempBuffer, 0, tempBuffer.Length);
                requestStream.Close();
 
                WebResponse uploadResponse = uploadImageHttpWebRequest.GetResponse();//this sends the request to the server and uploadsthe file
                uploadResponse.Close();//clean up the response
                uploadImageHttpWebRequest = null;//clean up therequest
                uploadResponse = null;
        }

        public void UploadFileToFTP(string source)
        {
            WebClient client = new WebClient();
            client.UploadFile("http://localhost:7190/SaveImage.aspx", "POST", source);
        }



        public void UploadFile(string localFile)
        {
            /*HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://localhost:7190/SaveImage.aspx");

            req.Method = "PUT";
            req.AllowWriteStreamBuffering = true;
            req.KeepAlive = false;

            // Retrieve request stream 
            Stream reqStream = req.GetRequestStream();

            // Open the local file
            FileStream rdr = new FileStream(localFile, FileMode.Open);

            // Allocate byte buffer to hold file contents
            byte[] inData = new byte[4096];

            // loop through the local file reading each data block
            //  and writing to the request stream buffer
            int bytesRead = rdr.Read(inData, 0, inData.Length);
            while (bytesRead > 0)
            {
                reqStream.Write(inData, 0, bytesRead);
                bytesRead = rdr.Read(inData, 0, inData.Length);
            }

            rdr.Close();
            reqStream.Close();

            req.GetResponse();*/
        }

        public void Export()
        {
            string dir = "C:";
            FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog();
            DialogResult result = dlg.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {

                dir = dlg.SelectedPath;
                Excel.Application xlApp;
                Excel.Workbook xlWorkBook;
                Excel.Worksheet xlWorkSheet;
                object misValue = System.Reflection.Missing.Value;
                Excel.Range chartRange;
                DateTime date = DateTime.Now;
                string link = "\\SanPham_" + date.Year.ToString() + date.Month.ToString() + date.Day.ToString() + "_" + date.Hour.ToString() + date.Minute + date.Second + ".xls";

                xlApp = new Excel.Application();

                xlApp.StandardFont = "Arial";
                xlApp.StandardFontSize = 11;
                xlWorkBook = xlApp.Workbooks.Add(misValue);
                xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
                xlWorkSheet.Name = "DANHSACHSP";

                xlWorkSheet.get_Range("A1", "I1").Merge(false);
                xlWorkSheet.get_Range("A1", "I1").Font.ColorIndex = 43;
                xlWorkSheet.get_Range("A1", "I1").Font.Size = 22;
                xlWorkSheet.get_Range("A1", "I1").HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                xlWorkSheet.Cells[1, 1] = "DANH SÁCH SẢN PHẨM";

                xlWorkSheet.get_Range("A2", "I2").Font.Bold = true;
                xlWorkSheet.get_Range("A2", "I2").Interior.ColorIndex = 43;
                xlWorkSheet.Cells[2, 1] = "STT";
                xlWorkSheet.Cells[2, 2] = "Mã sản phẩm";
                xlWorkSheet.Cells[2, 3] = "Tên sản phẩm";
                xlWorkSheet.Cells[2, 4] = "Chủ đề";
                xlWorkSheet.Cells[2, 5] = "Số mảnh";
                xlWorkSheet.Cells[2, 6] = "Giá bán";
                xlWorkSheet.Cells[2, 7] = "Ngày sản xuất";
                xlWorkSheet.Cells[2, 8] = "Bảo hành";
                xlWorkSheet.Cells[2, 9] = "Số lượng";

                for (int i = 0; i < ListSP.Count; i++)
                {
                    xlWorkSheet.Cells[i + 3, 1] = i + 1;
                    xlWorkSheet.Cells[i + 3, 2] = ListSP[i].MaSo;
                    xlWorkSheet.Cells[i + 3, 3] = ListSP[i].Ten;
                    xlWorkSheet.Cells[i + 3, 4] = ListSP[i].ChuDe.Ten;
                    xlWorkSheet.Cells[i + 3, 5] = ListSP[i].SoManhGhep;
                    xlWorkSheet.Cells[i + 3, 6] = ListSP[i].GiaBan;
                    xlWorkSheet.Cells[i + 3, 7] = ListSP[i].NgaySX.ToShortDateString();
                    xlWorkSheet.Cells[i + 3, 8] = ListSP[i].BaoHanh;
                    xlWorkSheet.Cells[i + 3, 9] = ListSP[i].SoLuong;
                }
                xlWorkSheet.Cells[ListSP.Count + 3, 8] = "Tổng cộng";
                xlWorkSheet.Cells[ListSP.Count + 3, 9] = string.Format("=SUM(I{0}:I{1})", 6, ListSP.Count + 2);
                xlWorkSheet.Cells[ListSP.Count + 3, 8].Font.Bold = true;
                xlWorkSheet.Cells[ListSP.Count + 3, 9].Font.Bold = true;

                chartRange = xlWorkSheet.get_Range("A1", "Z200");
                chartRange.Columns.AutoFit();

                try
                {
                    xlWorkBook.SaveAs(dir + link, Excel.XlFileFormat.xlWorkbookNormal, misValue, misValue, misValue, misValue, Excel.XlSaveAsAccessMode.xlExclusive, misValue, misValue, misValue, misValue, misValue);
                }
                catch
                {
                    MessageBox.Show("Không thể lưu file!");
                }
                finally
                {
                    xlWorkBook.Close(true, misValue, misValue);
                    xlApp.Quit();
                }

                releaseObject(xlApp);
                releaseObject(xlWorkBook);
                releaseObject(xlWorkSheet);

                MessageBox.Show("Đã tạo report tại " + dir + link);
            }


        }

        private void releaseObject(object obj)
        {
            try
            {
                System.Runtime.InteropServices.Marshal.ReleaseComObject(obj);
                obj = null;
            }
            catch (Exception ex)
            {
                obj = null;
                MessageBox.Show("Unable to release the Object " + ex.ToString());
            }
            finally
            {
                GC.Collect();
            }
        }
    }
}
